package com.edu.exam.entity.grading.audit;

import com.edu.exam.enums.audit.AuditTaskType;
import com.edu.exam.enums.common.TaskType;
import com.edu.exam.enums.grading.TaskPriority;
import com.edu.exam.enums.grading.TaskSource;
import com.edu.exam.enums.grading.GradingTaskStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 成绩审核任务实体类
 *
 * <p>成绩审核任务实体用于管理成绩审核的完整流程，包含
 * 任务提交、审核分配、审核处理、结果反馈等。确保成绩审核的规范性和可追溯性。</p>
 *
 * <p>所属模块：B-06 成绩管理模块</p>
 * <p>对应数据库表：grade_audit_management_task</p>
 *
 * <p>核心功能：
 * - 任务管理：管理审核任务的创建、分配、处理等全生命周期
 * - 状态控制：控制审核任务的各种状态转换
 * - 权限管理：管理审核任务的访问权限和操作权限
 * - 流程跟踪：跟踪审核任务的完整处理流程
 * - 结果反馈：记录审核结果和反馈意见</p>
 *
 * @author 系统生成
 * @version 1.0
 * @since 2025-11-10
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeAuditManagementTask {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 任务ID
     *
     * <p>审核任务的唯一标识符。</p>
     */
    @Column(name = "task_id", nullable = false, length = 50, unique = true)
    private String taskId;

    /**
     * 关联的成绩批次ID
     *
     * <p>关联的成绩批次标识符。</p>
     */
    @Column(name = "grade_batch_id", nullable = false, length = 50)
    private String gradeBatchId;

    /**
     * 课程ID
     *
     * <p>关联课程的唯一标识符。</p>
     */
    @Column(name = "course_id", nullable = false, length = 50)
    private String courseId;

    /**
     * 课程名称
     *
     * <p>关联课程的名称。</p>
     */
    @Column(name = "course_name", length = 200)
    private String courseName;

    /**
     * 班级ID
     *
     * <p>关联班级的唯一标识符。</p>
     */
    @Column(name = "class_id", length = 50)
    private String classId;

    /**
     * 班级名称
     *
     * <p>关联班级的名称。</p>
     */
    @Column(name = "class_name", length = 200)
    private String className;

    /**
     * 任务标题
     *
     * <p>审核任务的标题。</p>
     */
    @Column(name = "title", nullable = false, length = 200)
    private String title;

    /**
     * 任务描述
     *
     * <p>审核任务的详细描述。</p>
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;

    /**
     * 任务类型
     *
     * <p>审核任务的类型。
     * 支持的类型：GRADE_ENTRY（成绩录入审核）、GRADE_IMPORT（成绩导入审核）、GRADE_MODIFY（成绩修改审核）、GRADE_APPEAL（成绩申诉审核）、GRADE_CORRECTION（成绩更正审核）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "task_type", nullable = false, length = 30)
    @Builder.Default
    private AuditTaskType taskType = AuditTaskType.GRADE_ENTRY;

    /**
     * 任务状态
     *
     * <p>审核任务的当前状态。
     * 支持的状态：PENDING（待审核）、ASSIGNED（已分配）、IN_PROGRESS（审核中）、COMPLETED（已完成）、APPROVED（已通过）、REJECTED（已拒绝）、CANCELLED（已取消）、EXPIRED（已过期）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    @Builder.Default
    private GradingTaskStatus status = GradingTaskStatus.PENDING;

    /**
     * 任务优先级
     *
     * <p>审核任务的优先级。
     * 支持的级别：LOW（低）、NORMAL（普通）、HIGH（高）、URGENT（紧急）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "priority", nullable = false, length = 10)
    @Builder.Default
    private TaskPriority priority = TaskPriority.NORMAL;

    /**
     * 提交人ID
     *
     * <p>任务提交人的用户ID。</p>
     */
    @Column(name = "submitter_id", nullable = false, length = 50)
    private String submitterId;

    /**
     * 提交人姓名
     *
     * <p>任务提交人的姓名。</p>
     */
    @Column(name = "submitter_name", nullable = false, length = 100)
    private String submitterName;

    /**
     * 提交时间
     *
     * <p>任务提交的时间。</p>
     */
    @Column(name = "submit_time", nullable = false)
    private LocalDateTime submitTime;

    /**
     * 审核人ID
     *
     * <p>分配的审核人用户ID。</p>
     */
    @Column(name = "auditor_id", length = 50)
    private String auditorId;

    /**
     * 审核人姓名
     *
     * <p>分配的审核人姓名。</p>
     */
    @Column(name = "auditor_name", length = 100)
    private String auditorName;

    /**
     * 分配时间
     *
     * <p>任务分配给审核人的时间。</p>
     */
    @Column(name = "assign_time")
    private LocalDateTime assignTime;

    /**
     * 审核开始时间
     *
     * <p>审核人开始处理任务的时间。</p>
     */
    @Column(name = "audit_start_time")
    private LocalDateTime auditStartTime;

    /**
     * 完成时间
     *
     * <p>任务完成的时间。</p>
     */
    @Column(name = "complete_time")
    private LocalDateTime completeTime;

    /**
     * 截止时间
     *
     * <p>任务必须完成的截止时间。</p>
     */
    @Column(name = "deadline")
    private LocalDateTime deadline;

    /**
     * 审核意见
     *
     * <p>审核人的审核意见。</p>
     */
    @Column(name = "audit_opinion", columnDefinition = "TEXT")
    private String auditOpinion;

    /**
     * 拒绝原因
     *
     * <p>任务被拒绝的原因说明。</p>
     */
    @Column(name = "reject_reason", columnDefinition = "TEXT")
    private String rejectReason;

    /**
     * 审核结果
     *
     * <p>审核的结果数据，JSON格式存储。</p>
     */
    @Column(name = "audit_result", columnDefinition = "TEXT")
    private String auditResult;

    /**
     * 附件URL
     *
     * <p>任务相关附件的访问地址。</p>
     */
    @Column(name = "attachment_url", length = 500)
    private String attachmentUrl;

    /**
     * 附件数量
     *
     * <p>任务附件的数量。</p>
     */
    @Column(name = "attachment_count", nullable = false)
    @Builder.Default
    private Integer attachmentCount = 0;

    /**
     * 处理时长
     *
     * <p>任务处理的耗时（分钟）。</p>
     */
    @Column(name = "processing_duration_minutes")
    private Integer processingDurationMinutes;

    /**
     * 期望完成时间
     *
     * <p>期望任务完成的时间。</p>
     */
    @Column(name = "expected_completion_time")
    private LocalDateTime expectedCompletionTime;

    /**
     * 工作流ID
     *
     * <p>关联的工作流实例ID。</p>
     */
    @Column(name = "workflow_id", length = 50)
    private String workflowId;

    /**
     * 当前节点ID
     *
     * <p>当前处理的工作流节点ID。</p>
     */
    @Column(name = "current_node_id", length = 50)
    private String currentNodeId;

    /**
     * 重试次数
     *
     * <p>任务处理失败的重试次数。</p>
     */
    @Column(name = "retry_count", nullable = false)
    @Builder.Default
    private Integer retryCount = 0;

    /**
     * 最大重试次数
     *
     * <p>允许的最大重试次数。</p>
     */
    @Column(name = "max_retry_count")
    @Builder.Default
    private Integer maxRetryCount = 3;

    /**
     * 任务来源
     *
     * <p>任务的来源系统。
     * 支持的来源：GRADE_ENTRY（成绩录入系统）、GRADE_IMPORT（成绩导入系统）、GRADE_MANAGEMENT（成绩管理系统）、EXTERNAL_SYSTEM（外部系统）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "task_source", length = 20)
    @Builder.Default
    private TaskSource taskSource = TaskSource.GRADE_ENTRY;

    /**
     * 任务标签
     *
     * <p>JSON格式的任务标签，用于分类和过滤。</p>
     */
    @Column(name = "task_tags", columnDefinition = "TEXT")
    private String taskTags;

    /**
     * 任务备注
     *
     * <p>任务的备注信息。</p>
     */
    @Column(name = "task_notes", columnDefinition = "TEXT")
    private String taskNotes;

    /**
     * 扩展属性
     *
     * <p>JSON格式的扩展属性。</p>
     */
    @Column(name = "extended_properties", columnDefinition = "TEXT")
    private String extendedProperties;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 创建用户ID
     */
    @Column(name = "create_user_id", length = 50)
    private String createUserId;

    /**
     * 更新用户ID
     */
    @Column(name = "update_user_id", length = 50)
    private String updateUserId;

    /**
     * 版本号
     */
    @Column(name = "version", nullable = false)
    @Builder.Default
    private Integer version = 1;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    @Builder.Default
    private Boolean isDeleted = false;

    /**
     * 删除时间
     */
    @Column(name = "delete_time")
    private LocalDateTime deleteTime;

    /**
     * 删除用户ID
     */
    @Column(name = "delete_user_id", length = 50)
    private String deleteUserId;



}